12 point(int X
, int Y
) : x(X
), y(Y
) {}
17 ostream
& operator<< (ostream
& out
, const point
& c
)
19 out
<< "(" << c
.x
<< "," << c
.y
<< ")";
23 //P es un polígono ordenado anticlockwise.
24 //Si es clockwise, retorna el area negativa.
25 //Si no esta ordenado retorna pura mierda
26 double area(const vector
<point
> &p
){
28 for (int i
=0; i
<p
.size(); ++i
){
29 int j
= (i
+1) % p
.size();
30 r
+= p
[i
].x
*p
[j
].y
- p
[j
].x
*p
[i
].y
;
35 //retorna si c esta a la izquierda de el segmento AB
36 inline int cross(const point
&a
, const point
&b
, const point
&c
){
37 return (b
.x
-a
.x
)*(c
.y
-a
.y
) - (c
.x
-a
.x
)*(b
.y
-a
.y
);
40 //Self < that si esta a la derecha del segmento Pivot-That
41 bool angleCmp(const point
&self
, const point
&that
){
42 return( cross(pivot
, that
, self
) < 0 );
45 inline int distsqr(const point
&a
, const point
&b
){
46 return (a
.x
- b
.x
)*(a
.x
- b
.x
) + (a
.y
- b
.y
)*(a
.y
- b
.y
);
49 //vector p tiene los puntos ordenados anticlockwise
50 vector
<point
> graham(vector
<point
> p
){
52 sort(p
.begin(), p
.end(), angleCmp
);
53 //Ordenar por ángulo y eliminar repetidos.
54 //Si varios puntos tienen el mismo angulo se borran todos excepto el que esté más lejos
55 for (int i
=1; i
<p
.size()-1; ++i
){
56 if (cross(p
[0], p
[i
], p
[i
+1]) == 0){ //Si son colineales...
57 if (distsqr(p
[0], p
[i
]) < distsqr(p
[0], p
[i
+1])){ //Borrar el mas cercano
58 p
.erase(p
.begin() + i
);
60 p
.erase(p
.begin() + i
+ 1);
66 vector
<point
> chull(p
.begin(), p
.begin()+3);
69 for (int i
=3; i
<p
.size(); ++i
){
70 while ( chull
.size() >= 2 && cross(chull
[chull
.size()-2], chull
[chull
.size()-1], p
[i
]) < 0){
71 chull
.erase(chull
.end() - 1);
73 chull
.push_back(p
[i
]);
82 while (cin
>> n
&& n
){
84 point
min(10000, 10000);
86 for (int i
=0; i
<n
; ++i
){
89 p
.push_back(point(x
,y
));
90 if (y
< min
.y
|| (y
== min
.y
&& x
< min
.x
)){
95 double tileArea
= fabs(area(p
));
97 //Destruye el orden cw|ccw poligono, pero hay que hacerlo por que Graham necesita el pivote en p[0]
98 swap(p
[0], p
[minPos
]);
100 double chullArea
= fabs(area(graham(p
)));
102 printf("Tile #%d\n", tileNo
++);
103 printf("Wasted Space = %.2f \%\n\n", (chullArea
- tileArea
) * 100.0 / chullArea
);